<template>
  <view class="device-report">
    <view class="title title-bind">
      <view class="title-width ellipsis">
        <view class="name-box" v-if="deviceStatus === true">
          <text class="name ellipsis" v-if="registerName">
            {{ registerName }}
          </text>
          <text v-if="registerName && deviceSn" style="margin: 1px 8rpx 0 10rpx; font-size: 30rpx">
            |
          </text>
          <text class="sn ellipsis" v-if="deviceSn">
            {{ deviceSn }}
          </text>
        </view>
      </view>
      <view class="help">
        <uv-text
          suffixIcon="question-circle-fill"
          color="#666666"
          size="13"
          text="操作指引"
          @click="operating"
        ></uv-text>
      </view>
    </view>
    <view class="content">
      <view class="battery">
        <text class="text" v-if="capacity.val > -1">{{ capacity.val }}%</text>
        <view class="main-body" :style="{ border: `3rpx solid ${capacity.border}` }">
          <view class="electricity">
            <view v-if="capacity.val === -1" class="capacity-empty"></view>
            <view
              v-if="capacity.val > 0"
              class="capacity"
              :style="{
                width: capacity.val + '%',
                background: capacity.color,
              }"
            ></view>
          </view>
        </view>
        <view class="right-head" :style="{ background: capacity.border }"></view>
      </view>
      <view v-if="!isLogin" class="content-box">
        <view class="process-img">
          <!-- 手机绑定 -->
          <view class="bind-icon">
            <view>
              <uv-image src="/static/images/phone.png" width="160rpx" height="160rpx">
                <template v-slot:loading>
                  <uv-loading-icon mode="spinner"></uv-loading-icon>
                </template>
              </uv-image>
              <uv-text
                size="12"
                type="info"
                align="center"
                prefixIcon="close-circle"
                :iconStyle="{ color: '#909399', fontSize: '14px', marginRight: '4rpx' }"
                text="未绑定"
              ></uv-text>
            </view>
          </view>
          <!-- 连接线 -->
          <view style="width: 100%; margin-bottom: 30rpx">
            <uv-image src="/static/images/connect.png" width="100%" height="2rpx">
              <template v-slot:loading>
                <uv-loading-icon mode="spinner"></uv-loading-icon>
              </template>
            </uv-image>
            <uv-text text=" "></uv-text>
          </view>
          <!-- hub -->
          <view class="bind-icon">
            <view>
              <uv-image src="/static/images/hub.png" width="160rpx" height="160rpx">
                <template v-slot:loading>
                  <uv-loading-icon mode="spinner"></uv-loading-icon>
                </template>
              </uv-image>
              <uv-text
                size="12"
                type="info"
                align="center"
                prefixIcon="close-circle"
                :iconStyle="{ color: '#909399', fontSize: '14px', marginRight: '4rpx' }"
                text="HUB离线"
              ></uv-text>
            </view>
          </view>
          <!-- 连接线 -->
          <view style="width: 100%; margin-bottom: 30rpx">
            <uv-image src="/static/images/connect.png" width="100%" height="2rpx">
              <template v-slot:loading>
                <uv-loading-icon mode="spinner"></uv-loading-icon>
              </template>
            </uv-image>
            <uv-text text=" "></uv-text>
          </view>
          <!-- 蓝牙 -->
          <view class="bind-icon">
            <view>
              <uv-image src="/static/images/ecg.png" width="160rpx" height="160rpx">
                <template v-slot:loading>
                  <uv-loading-icon mode="spinner"></uv-loading-icon>
                </template>
              </uv-image>
              <uv-text
                size="12"
                type="info"
                align="center"
                prefixIcon="close-circle"
                :iconStyle="{ color: '#909399', fontSize: '14px', marginRight: '4rpx' }"
                text="记录仪离线"
              ></uv-text>
            </view>
          </view>
        </view>
        <!-- 登记 -->
        <view class="button-box">
          <wd-button block type="primary" @click="scanQRcodes">扫码绑定设备</wd-button>
        </view>
      </view>
      <view v-else class="content-box">
        <view class="process-img">
          <!-- 手机绑定 -->
          <view class="bind-icon">
            <view v-if="deviceStatus">
              <uv-image src="/static/images/phone-bind.png" width="160rpx" height="160rpx">
                <template v-slot:loading>
                  <uv-loading-icon mode="spinner"></uv-loading-icon>
                </template>
              </uv-image>
              <uv-text
                size="12"
                type="primary"
                align="center"
                prefixIcon="checkmark-circle"
                :iconStyle="{ color: '#e50038', fontSize: '14px', marginRight: '4rpx' }"
                text="已绑定"
              ></uv-text>
            </view>
            <view v-else>
              <uv-image src="/static/images/phone.png" width="160rpx" height="160rpx">
                <template v-slot:loading>
                  <uv-loading-icon mode="spinner"></uv-loading-icon>
                </template>
              </uv-image>
              <uv-text
                size="12"
                type="info"
                align="center"
                prefixIcon="close-circle"
                :iconStyle="{ color: '#909399', fontSize: '14px', marginRight: '4rpx' }"
                text="未绑定"
              ></uv-text>
            </view>
          </view>
          <!-- 连接线 -->
          <view style="width: 100%; margin-bottom: 30rpx">
            <uv-image
              v-if="deviceStatus === true"
              src="/static/images/connect-onLine.png"
              width="100%"
              height="2rpx"
            >
              <template v-slot:loading>
                <uv-loading-icon mode="spinner"></uv-loading-icon>
              </template>
            </uv-image>
            <uv-image v-else src="/static/images/connect.png" width="100%" height="2rpx">
              <template v-slot:loading>
                <uv-loading-icon mode="spinner"></uv-loading-icon>
              </template>
            </uv-image>
            <uv-text text=" "></uv-text>
          </view>
          <!-- hub -->
          <view class="bind-icon">
            <view v-if="deviceStatus === true && hubStatus === true">
              <uv-image src="/static/images/hub-onLine.png" width="160rpx" height="160rpx">
                <template v-slot:loading>
                  <uv-loading-icon mode="spinner"></uv-loading-icon>
                </template>
              </uv-image>
              <uv-text
                size="12"
                type="primary"
                align="center"
                prefixIcon="checkmark-circle"
                :iconStyle="{ color: '#e50038', fontSize: '14px', marginRight: '4rpx' }"
                text="HUB在线"
              ></uv-text>
            </view>
            <view v-else>
              <uv-image src="/static/images/hub.png" width="160rpx" height="160rpx">
                <template v-slot:loading>
                  <uv-loading-icon mode="spinner"></uv-loading-icon>
                </template>
              </uv-image>
              <uv-text
                size="12"
                type="info"
                align="center"
                prefixIcon="close-circle"
                :iconStyle="{ color: '#909399', fontSize: '14px', marginRight: '4rpx' }"
                text="HUB离线"
              ></uv-text>
            </view>
          </view>
          <!-- 连接线 -->
          <view style="width: 100%; margin-bottom: 30rpx">
            <uv-image
              v-if="deviceStatus === true && hubStatus === true"
              src="/static/images/connect-onLine.png"
              width="100%"
              height="2rpx"
            >
              <template v-slot:loading>
                <uv-loading-icon mode="spinner"></uv-loading-icon>
              </template>
            </uv-image>
            <uv-image v-else src="/static/images/connect.png" width="100%" height="2rpx">
              <template v-slot:loading>
                <uv-loading-icon mode="spinner"></uv-loading-icon>
              </template>
            </uv-image>
            <uv-text text=" "></uv-text>
          </view>
          <!-- 蓝牙 -->
          <view class="bind-icon">
            <view v-if="deviceStatus === true && hubStatus === true && blueStatus === true">
              <uv-image src="/static/images/ecg-onLine.png" width="160rpx" height="160rpx">
                <template v-slot:loading>
                  <uv-loading-icon mode="spinner"></uv-loading-icon>
                </template>
              </uv-image>
              <uv-text
                size="12"
                type="primary"
                align="center"
                prefixIcon="checkmark-circle"
                :iconStyle="{ color: '#e50038', fontSize: '14px', marginRight: '4rpx' }"
                text="记录仪在线"
              ></uv-text>
            </view>
            <view v-else>
              <uv-image src="/static/images/ecg.png" width="160rpx" height="160rpx">
                <template v-slot:loading>
                  <uv-loading-icon mode="spinner"></uv-loading-icon>
                </template>
              </uv-image>
              <uv-text
                size="12"
                type="info"
                align="center"
                prefixIcon="close-circle"
                :iconStyle="{ color: '#909399', fontSize: '14px', marginRight: '4rpx' }"
                text="记录仪离线"
              ></uv-text>
            </view>
          </view>
        </view>
        <view v-if="deviceStatus" style="width: 100%">
          <view v-if="!hubStatus || !blueStatus" class="info button-box" style="text-align: center">
            <view v-if="!hubStatus">
              <text style="font-size: 24rpx; color: #909399; text-align: left">
                2、检查HUB是否连接电源，"
                <text style="color: #5ac725">绿灯</text>
                " 亮起并闪烁
              </text>
            </view>
            <view v-if="!blueStatus" class="mt-3">
              <text style="font-size: 24rpx; color: #909399; text-align: left">
                3、将记录仪开机并靠近HUB，直到"
                <text style="color: #3c9cff">蓝灯</text>
                " 亮起并闪烁
              </text>
            </view>
          </view>
        </view>
        <!-- 登记 -->
        <view class="button-box" v-if="!deviceStatus">
          <wd-button block type="primary" @click="scanQRcodes">扫码绑定设备</wd-button>
        </view>
        <view class="button-box" v-else-if="hubStatus === true && blueStatus === true">
          <view v-if="operationStatus === 1">
            <uv-button type="primary" shape="circle" @click="reservation">
              {{ processName === 2 ? '继续' : '预约' }}登记
            </uv-button>
          </view>
          <view v-if="operationStatus === 2">
            <uv-button
              type="primary"
              :loading="monitoringLading"
              :disabled="monitoringLading"
              :loadingText="`验证设备状态中，请稍等（${countdownTime}s）`"
              @click="startMonitoring"
              shape="circle"
              v-if="operationStatus == 2"
            >
              启动监测
            </uv-button>
          </view>

          <view class="dynamic-text" v-if="operationStatus > 2 && operationStatus <= 4">
            <view>正在监测中：{{ timingTime || '--小时--分--秒' }}</view>
          </view>

          <view v-if="operationStatus === -1">
            <uv-text
              prefixIcon="error-circle-fill"
              iconStyle="font-size: 34rpx;;color:#f56c6c;margin-right: 10rpx;"
              customStyle="font-size: 32rpx; font-weight: 500;color: #e50038;"
              text="检测到当前记录仪状态异常"
              align="center"
            ></uv-text>
            <view style="margin-top: 40rpx; font-size: 26rpx; color: #2f2f2f">
              可尝试将记录仪重新上电后，刷新页面恢复状态。或联系客服解决
            </view>
          </view>
          <view v-if="operationStatus === -2" style="margin-bottom: 40rpx">
            <uv-text
              prefixIcon="error-circle-fill"
              iconStyle="font-size: 34rpx;color:#f56c6c;margin-right: 10rpx;"
              customStyle="font-size: 32rpx; font-weight: 500;color: #2f2f2f;"
              text="检测到记录仪异常离线，将主动结束监测"
              align="center"
            ></uv-text>

            <uv-button
              type="primary"
              shape="circle"
              plain
              :hairline="false"
              :loading="true"
              :disabled="true"
              customStyle="background:#FBEDEC;border:none;margin-top:60rpx;"
              :loadingText="`主动结束监测中...`"
            >
              结束监测
            </uv-button>
          </view>
          <view v-if="operationStatus === 4">
            <uv-button
              type="primary"
              shape="circle"
              plain
              :hairline="false"
              customStyle="background:#FBEDEC;border:none"
              @click="endMonitoring"
            >
              结束监测
            </uv-button>
          </view>
          <view class="circle-loading" v-if="operationStatus === 5">
            <wd-circle
              v-model="current"
              :text="`${current}%`"
              custom-style="font-size:26rpx;"
              layer-color="#e9e9e9"
              :stroke-width="8"
              :size="60"
              color="#E50038"
            ></wd-circle>
            <view style="margin-top: 30rpx">数据上传中，请耐心等待结果</view>
          </view>
        </view>
      </view>
    </view>
    <wd-message-box></wd-message-box>
    <uv-toast ref="toastRef"></uv-toast>
  </view>
</template>
<script lang="js" setup>
import useScan from '@/pages/home/method/useScan'
import {
  bindDevice,
  getDeviceStatus,
  startMonitor,
  stopMonitor,
  getDevices,
  getExamStatus,
  unbindDevice,
  queryEcgMsg,
  getDeviceElectric,
} from '@/service/index/default'
import MQtt from '@/pages/home/method/useMQtt'
import { isLoginEd, getUser, loginJump, getSn, setSn, subscribe } from '@/utils/publicMethods'
// props
const props = defineProps({
  sn: {
    type: String,
    default: '',
  },
  name: {
    type: String,
    default: '',
  },
  model: {
    type: String,
    default: '',
  },
})

/*
设备状态:
  0: 未绑定
  1：已绑定
*/
const deviceStatus = ref(false)
/*
可显示操作状态:
  1：预约登记
  2：开启监测
  3: 继续监测
  4：结束监测
  5：上传等待
  -1: 页面异常
  -2：记录仪绿灯不在线
*/
const operationStatus = ref(1)
// hub在线
const hubStatus = ref(false)
// 蓝牙在线
const blueStatus = ref(false)
// 登记人
const registerName = ref('')
// sn
const deviceSn = ref('')
// 报告数据
const reportCount = ref(0)
// 按钮状态
const monitoringLading = ref(false)
// 检查时间
const examDatetime = ref('')
// 基本信息
const userInfo_ = ref({})
// 是否登录
const isLogin = ref(false)
// 电量设置
const capacity = reactive({
  val: -1,
  color: '#cccccc',
  border: '#cccccc',
})
// 上传进度
const current = ref(0)
// 上传进度对应的登记名称
const processName = ref(0)

const initData = () => {
  deviceStatus.value = false
  operationStatus.value = 1
  hubStatus.value = false
  blueStatus.value = false
  registerName.value = ''
  timingTime.value = null
  reportCount.value = 0
  examDatetime.value = ''
  monitoringLading.value = false
  deviceSn.value = ''
  processName.value = 0
  userInfo_.value = {}
  current.value = 0
  clearCountdown()
  clearTime()
}

const emits = defineEmits(['update:status', 'update:sn', 'update:name', 'update:model'])
const initProps = () => {
  emits('update:status', '')
  emits('update:sn', '')
  emits('update:name', '')
  emits('update:model', '')
}

// 登录
const login = () => {
  uni.navigateTo({ url: '/pages-sub/login/index' })
}

// 操作指引
const operating = () => {
  uni.navigateTo({ url: '/pages-sub/operating/index' }, 1000)
}

// 查看报告
const viewReport = () => {
  uni.navigateTo({ url: '/pages-sub/viewReport/index' }, 1000)
}

// 扫码
const { GetWxUrlParam } = useScan()
const scanQRcodes = () => {
  if (!isLogin.value) {
    loginJump()
    return
  }
  uni.scanCode({
    barCodeInput: true,
    success: async (res) => {
      const params = GetWxUrlParam(res?.result)
      await getDevices_()
      deviceStatus.value = !!deviceSn.value
      binding(params)
    },
    fail: (err) => {
      console.log('扫描失败：', err)
    },
  })
}

// 登录人是否绑定了设备
const getDevices_ = async () => {
  const { data, code, error } = await getDevices({ userId: userInfo_.value.userId })
  if (code !== 200) {
    uni.showToast({
      title: `${error}`,
      icon: 'none',
    })
    deviceSn.value = ''
    setSn('')
    return
  }
  deviceSn.value = data?.length ? data[0].sn : ''
  setSn(deviceSn.value)
}

// 预约登记
const reservation = () => {
  uni.navigateTo({ url: '/pages-sub/reservation/index' }, 1000)
}

// 登录人是否存在检查单
const getExamStatus_ = async (sn, newBind) => {
  // 是否绑定
  examDatetime.value = ''
  const { data, code, error } = await getExamStatus({
    userId: userInfo_.value.userId,
    sn: sn,
  })
  if (code !== 200) {
    uni.showToast({
      title: `${error}`,
      icon: 'none',
    })
    return null
  }
  if (newBind) {
    registerName.value = ''
    examDatetime.value = ''
  } else {
    registerName.value = data.name
    examDatetime.value = data.examDatetime
  }
  return data
}

// 当前设备是否存在绑定
const getDeviceStatus_ = async (sn, getUserId) => {
  const { data, code, error } = await getDeviceStatus({ sn })
  if (code !== 200) {
    uni.showToast({
      title: `${error}`,
      icon: 'none',
    })
    return false
  }
  hubStatus.value = data?.connEvent === 1 ? true : false
  blueStatus.value = data?.blueConn === 1 ? true : false
  operationStatus.value = data?.process === 2 ? 1 : data?.process === 1 ? 5 : operationStatus.value //0未处理1处理中2处理完成
  processName.value = data?.process //0未处理1处理中2处理完成
  if (getUserId) {
    return { bind: data?.bind, userId: data?.userId }
  } else {
    return !!data?.bind
  }
}

// 解除绑定
const toastRef = ref(null)
const unbindDevice_ = async (sn, userId) => {
  const { data, code, error } = await unbindDevice({ userId: userId || userInfo_.value.userId, sn })
  if (code !== 200) {
    uni.showToast({
      title: `${error}`,
      icon: 'none',
    })
    return false
  }
  deviceStatus.value = false
  setSn('')
  return true
}

// 绑定设备
const bindDevice_ = async (params, isReplace) => {
  const { data, code, error } = await bindDevice({
    ...params,
    userId: userInfo_.value.userId,
  })
  if (code !== 200) {
    uni.showToast({
      title: `${error}`,
      icon: 'none',
    })
    return false
  }
  uni.showToast({
    title: isReplace ? '替换成功！' : '绑定成功！',
    icon: 'success',
  })
  deviceStatus.value = true
  return true
}

// 查询ecg监测状态
const queryEcgMsg_ = async (sn) => {
  const { code, error } = await queryEcgMsg({ sn })
  if (code !== 200) {
    uni.showToast({
      title: `${error}`,
      icon: 'none',
    })
    return false
  }
}

// 通信
const binding = async (params) => {
  const { sn, model: deviceType, name: deviceName } = params
  initProps()
  // 1、直接进来，页面没有sn号
  if (!sn) {
    // 设备有绑定
    if (deviceSn.value) {
      deviceStatus.value = true
      createConnection_(deviceSn.value)
      // 是否有检查单在监测中
      const examStatus = await getExamStatus_(deviceSn.value)
      // 在监测中，则继续监测，否则是否在预约中，则开启监测，否则开启预约
      if (examStatus?.monitoring === 1) {
        operationStatus.value = 4
        return
      } else if (examStatus?.status === 1) {
        operationStatus.value = 2
        return
      } else {
        operationStatus.value = 1
        return
      }
    }
  }
  if (sn) {
    // 2、页面有sn号、扫码进来，当前用户有绑定设备
    if (deviceSn.value) {
      deviceStatus.value = true
      createConnection_(deviceSn.value)
      // 3、当前用户绑定的设备sn和扫码进来的sn是否相同，相同
      if (deviceSn.value === sn) {
        // 是否有检查单在监测中
        const examStatus = await getExamStatus_(deviceSn.value)
        // 在监测中，则继续监测，否则是否在预约中，则开启监测，否则开启预约
        if (examStatus?.monitoring === 1) {
          operationStatus.value = 4
          return
        } else if (examStatus?.status === 1) {
          operationStatus.value = 2
          return
        } else {
          operationStatus.value = 1
          return
        }
      } else {
        // 4、用户有绑定，但和扫码进来的sn不同
        // 当前用户是否有检查单在监测中、预约中，非预约非监测才能替换设备
        const examStatus = await getExamStatus_(deviceSn.value)
        //  4-1、在监测中
        if (examStatus?.monitoring === 1) {
          uni.showToast({
            title: `您当前存在监测中的检查单，无法重新绑定`,
            icon: 'none',
          })
          operationStatus.value = 4
          return
        } else if (examStatus?.status === 1) {
          uni.showToast({
            title: `您当前存在预约中的检查单，无法重新绑定`,
            icon: 'none',
          })
          operationStatus.value = 2
          return
        }
        // ------------ 替换设备 --------------
        // 4-2、当前用户绑定的设备在非预约非监测中，新设备也要判断是否在预约和监测中
        const { bind, userId } = await getDeviceStatus_(sn, true)
        if (!bind) {
          // 不在绑定中，直接绑定设备
          const bindStatus = await bindDevice_({ sn, deviceType, deviceName })
          if (!bindStatus) return
          deviceSn.value = sn
          setSn(sn)
          createConnection_(sn)
        }
        // 如果在绑定中、当前设备是否在监测中
        const examStatus2 = await getExamStatus_(sn, true)
        if (examStatus2.monitoring === 1) {
          uni.showToast({
            title: `当前设备正在监测中，无法绑定`,
            icon: 'none',
          })
          return
        }
        // 在绑定中，未在监测中，解绑
        const status = await unbindDevice_(sn, userId)
        if (!status) return
        // 再绑定
        const bindStatus = await bindDevice_({ sn, deviceType, deviceName })
        if (!bindStatus) return
        registerName.value = examStatus.name
        examDatetime.value = examStatus.examDatetime
        deviceSn.value = sn
        setSn(sn)
        createConnection_(sn)
      }
    } else {
      // 5-1、页面有sn号、扫码进来，当前用户无绑定、需要查询当前设备是否绑定
      const { bind, userId } = await getDeviceStatus_(sn, true)
      if (!bind) {
        // 不在绑定中，直接绑定设备
        const bindStatus = await bindDevice_({ sn, deviceType, deviceName })
        if (!bindStatus) return
        deviceSn.value = sn
        setSn(sn)
        createConnection_(sn)
      }
      // 如果在绑定中、当前设备是否在监测中
      const examStatus = await getExamStatus_(sn, true)
      if (examStatus.monitoring === 1) {
        uni.showToast({
          title: `设备正在监测中，无法绑定`,
          icon: 'none',
        })
        return
      }
      // 在绑定中，未在监测中，解绑
      const status = await unbindDevice_(sn, userId)
      if (!status) return
      // 再绑定
      const bindStatus = await bindDevice_({ sn, deviceType, deviceName })
      if (!bindStatus) return
      registerName.value = examStatus.name
      examDatetime.value = examStatus.examDatetime
      deviceSn.value = sn
      setSn(sn)
      createConnection_(sn)
    }
  }
}

// mqtt获取蓝牙状态
const topicList = ref([])
const { createConnection, doSubscribe, setOperation, destroyConnection, mqttData, doUnSubscribe } =
  MQtt()
const createConnection_ = async (sn) => {
  // 如果当前用户的绑定的sn和MQTT中的sn不一致，则断开连接
  if (setOperation.value.sn && setOperation.value.sn !== sn) {
    const isContent = await destroyConnection()
    console.log(isContent, '用户sn不一致，断开连接', deviceSn.value, sn)
  }
  if (!userInfo_.value.phoneNumber) {
    const isContent = await destroyConnection()
    console.log(isContent, '用户未登录，断开连接')
    return
  }
  // 订阅前先ping一下
  await getDeviceStatus_(sn)
  // 连接-订阅
  topicList.value = [
    `/min/${sn}/hub/status_reply`, //获取hub状态  0
    `/min/${sn}/status_reply`, //获取ecg状态（蓝牙）1
    `/min/${sn}/start_reply`, //开启监测  2
    `/min/${sn}/query_reply`, // 获取监测状态 3
    `/min/${sn}/stop_reply`, // 停止监测  4
    `/min/${sn}/progress`, //上传进度显示 5
  ]
  setOperation.value.sn = sn
  setOperation.value.topic = topicList.value
  //连接
  await createConnection(userInfo_.value.phoneNumber)
  //订阅
  //再查询ecg状态信息
  const doStatus = await doSubscribe()

  if (!doStatus) {
    console.log('订阅失败：', doStatus)
    mqttData.value.client = null
    await createConnection(userInfo_.value.phoneNumber)
    await doSubscribe()
    await doSubscribe(`/min/${sn}/realtime_data`, 0)
  } else {
    await doSubscribe(`/min/${sn}/realtime_data`, 0)
  }
  await queryEcgMsg_(sn) // mqtt连接后，查询ecg状态，后台通过query_reply返回结果
}

onUnload(() => {
  uni.$off('subscription')
  uni.$off('register')
  uni.$off('weChartInit')
  uni.$off('loginEvent')
})

let clearPowerTime = false
watch(
  () => operationStatus.value,
  (newValue) => {
    console.log(`watch_监测状态变化`, newValue)
    // 开发调试
    // operationStatus.value = 5
    // return
    if (newValue !== 2) {
      clearCountdown() // 清除按钮计时
    }
    if (newValue !== 5) {
      current.value = 0
    }
    // 状态当为operationStatus = 4，则开始计时
    if (newValue === 4) {
      clearTime() // 清除监测计时
      reckonTime() // 监测计时
      clearPowerTime = true
      powerTime() // 电量计时
      return
    }
    initCapacity() // 初始化电量
    clearTime() // 清除监测计时
    uni.$emit('stopEcgInit', 'watch')
  },
)

// 下拉重新连接盒子
const deviceScroll = async () => {
  isLogin.value = isLoginEd()
  if (!isLogin.value) {
    initData()
    return
  }
  userInfo_.value = getUser()
  // 用户是否绑定，并获取hub/记录仪在后台是否有缓存
  await getDevices_()
  deviceStatus.value = !!deviceSn.value
  // 连接
  await binding({ sn: props.sn, name: props.name, model: props.model })
}

onShow(async () => {
  isLogin.value = isLoginEd()
  if (!isLogin.value) {
    initData()
    return
  }
  userInfo_.value = getUser()
  // 用户是否绑定
  await getDevices_()
  deviceStatus.value = !!deviceSn.value

  // 是否在监测中
  if (
    deviceStatus.value &&
    hubStatus.value === true &&
    blueStatus.value === true &&
    operationStatus.value > 1
  ) {
    await getExamStatus_(deviceSn.value)
    return
  }
  // 开始通信
  await binding({ sn: props.sn, name: props.name, model: props.model })
})

onLoad(() => {
  uni.$on('loginEvent', (option) => {
    if (!option) {
      initData()
      doUnSubscribe()
      destroyConnection()
    }
  })
  // 由后台切换回前台
  uni.$on('weChartInit', (option) => {
    clearTime() // 清除监测计时
    if (option === 'onShow' && operationStatus.value === 4 && hubStatus.value && blueStatus.value) {
      console.log('mqtt连接状态', mqttData.value.client?.connected, examDatetime.value)
      reckonTime() // 监测计时
      return
    }
  })
  // 订阅消息
  uni.$on('subscription', async (option) => {
    const sn = getSn()
    const parts = option.topic.split('/')[2] // 根据 '/' 分隔字符串
    // 是否和当前用户的sn号一致
    if (sn !== parts) {
      console.log('非当前用户设备，无需订阅消息！: ', sn, parts)
      return
    }

    if (!option.topic.includes('realtime_data')) {
      console.log(`接收${option.topic}订阅消息:`, option.message)
    }

    // hub状态
    if (option.topic === topicList.value[0]) {
      hubStatus.value = option.message?.alive ? true : false
      if (!hubStatus.value) {
        blueStatus.value = false
        getDeviceStatus_(sn)
      }
    }

    // 蓝牙状态
    if (option.topic === topicList.value[1]) {
      if (!option.message?.connected) {
        blueStatus.value = false
      } else {
        hubStatus.value = true
        blueStatus.value = true
      }
    }

    // 开启监测计时
    if (option.topic === topicList.value[2]) {
      operationStatus.value = 4
    }

    // 获取监测状态,如果在监测中，显示结束监测
    if (option.topic === topicList.value[3]) {
      // // 开发调试
      // operationStatus.value = 5
      // return
      const startIndex = option.topic.indexOf('/min/') + 5
      const endIndex = option.topic.indexOf('/query_reply')
      const sn = option.topic.substring(startIndex, endIndex)
      // 2秒后，如果hub没在线，ping一下获取hub的状态
      clearCountdown() //清除按钮计时
      setTimeout(() => {
        if (!hubStatus.value) getDeviceStatus_(sn)
      }, 1000)
      // 如果在监测中，可以结束监测
      if (option.message?.monitor) {
        // 添加一个异常状态，如果此时没有检查单，则提示用户设备异常
        const examStatus = await getExamStatus_(sn)
        if (!examStatus?.examId) {
          operationStatus.value = -1
        } else {
          operationStatus.value = 4
        }
        return
      }
      // 如果在上传中，等待数据处理完毕
      if (option.message?.processing) {
        operationStatus.value = 5
        return
      }
      // 即不在监测也不在上传中，则重新获取监测状态和检查单状态
      const examStatus = await getExamStatus_(sn)
      // 在监测中且设备在线，用户重新上电，收到监测状态离线消息后，则自动结束监测
      if (examStatus?.monitoring === 1 && blueStatus.value === true && hubStatus.value === true) {
        operationStatus.value = -2
        setTimeout(async () => {
          await stopMonitor_()
        }, 3000)
        return
      }
      operationStatus.value = examStatus?.monitoring === 1 ? 4 : examStatus?.status === 1 ? 2 : 1
      console.log(
        `检查单接口缓存：监测状态：${examStatus?.monitoring}、检查单状态：${examStatus?.status}`,
      )
    }

    // 结束监测，等待数据上传
    if (option.topic === topicList.value[4]) {
      operationStatus.value = 5
    }

    // 获取上传进度
    if (option.topic === topicList.value[5]) {
      operationStatus.value = 5

      if (option.message?.noProgress) {
        let ii = 1
        setInterval(() => {
          if (ii > 4) {
            clearInterval()
            return
          }
          if (ii === 1) {
            current.value = Math.floor(Math.random() * 10) + 1
          }
          if (ii === 2) {
            current.value = Math.floor(Math.random() * (70 - 40 + 1)) + 50
          }
          if (ii === 3) {
            current.value = 100
          }
          if (ii === 4) {
            uni.showToast({
              title: '数据上传完成！',
              icon: 'success',
            })
            operationStatus.value = 1
            processName.value = 2
          }
          ii++
        }, 1500)
      } else {
        current.value =
          Math.floor(option.message?.progress) < 1 ? 1 : Math.floor(option.message?.progress)
        if (option.message?.progress === 100) {
          setTimeout(() => {
            uni.showToast({
              title: '数据上传完成！',
              icon: 'success',
            })
            operationStatus.value = 1
            processName.value = 2
          }, 1500)
        }
      }
    }
  })
  // 登记成功
  uni.$on('register', (params) => {
    if (params?.status) {
      operationStatus.value = 2
      registerName.value = params.name
    }
  })
})

let time = 3000
let powerTimer = null
// 电量计时
const powerTime = async () => {
  if (!clearPowerTime) {
    return
  }
  if (powerTimer !== null) {
    clearTimeout(powerTimer)
  }
  time = capacity.val === -1 ? 3000 : capacity.val > 1 ? 60000 * 60 * 2 : 60000 * 30
  powerTimer = setTimeout(powerTime, time)
  await getDeviceElectric_(time <= 3000 ? true : false)
}

const initCapacity = () => {
  capacity.val = -1
  capacity.color = '#cccccc'
  capacity.border = '#cccccc'
  clearPowerTime = false
}

const getDeviceElectric_ = async (init = false) => {
  const { data, code, error } = await getDeviceElectric({ sn: deviceSn.value })
  if (code !== 200) {
    initCapacity()
    return false
  }
  const electric = data?.electric
  switch (electric) {
    case 0:
      capacity.val = 0
      capacity.color = '#e50038'
      capacity.border = '#ff9393'
      break
    case 1:
      capacity.val = 25
      capacity.color = '#f0ad4e'
      capacity.border = '#666666'
      break
    case 2:
      capacity.val = 50
      capacity.color = '#f0ad4e'
      capacity.border = '#666666'
      break
    case 3:
      capacity.val = 75
      capacity.color = '#4cd964'
      capacity.border = '#666666'
      break
    case 4:
      capacity.val = 100
      capacity.color = '#4cd964'
      capacity.border = '#666666'
      break
    default:
      capacity.val = -1
      capacity.color = '#cccccc'
      capacity.border = '#cccccc'
      break
  }
}

// 开启监测
const timingTime = ref('')
const startMonitoring = async () => {
  // 订阅
  await subscribe(userInfo_.value.userId)
  countdown()
  const { data, code, error } = await startMonitor({
    sn: deviceSn.value,
    userId: userInfo_.value.userId,
  })
  if (code !== 200) {
    uni.showToast({
      title: `${error}`,
      icon: 'none',
    })
    clearCountdown()
    return false
  }
  await getExamStatus_(deviceSn.value)
}

// 结束监测
const endMonitoring = async () => {
  uni.showModal({
    title: '提示',
    content: '确定结束监测吗？',
    showCancel: true,
    cancelText: '取消',
    confirmText: '确定',
    confirmColor: '#e50038',
    cancelColor: '#999999',
    success: async (res) => {
      if (res.confirm) {
        await stopMonitor_()
        uni.$emit('stopEcgInit', 'stopMonitoring')
      }
    },
  })
}

const stopMonitor_ = async () => {
  const { data, code, error } = await stopMonitor({
    sn: deviceSn.value,
    userId: userInfo_.value.userId,
  })
  if (code !== 200) {
    uni.showToast({
      title: `${error}`,
      icon: 'none',
    })
    return false
  }
  operationStatus.value = 5
}

// 按钮倒计时
let countdownTimer = null
const countdownTime = ref(15)
const countdown = () => {
  countdownTime.value = 15
  monitoringLading.value = true
  if (countdownTimer) {
    clearInterval(countdownTimer)
  }
  countdownTimer = setInterval(() => {
    countdownTime.value-- // 每次减少一秒
    if (countdownTime.value <= 0) {
      clearInterval(countdownTimer) // 倒计时结束，清除定时器
      countdownTimer = null
      monitoringLading.value = false
      uni.showToast({
        title: `启动失败，请刷新页面重试`,
        icon: 'none',
      })
    }
  }, 1000)
}

// 结束按钮倒计时
const clearCountdown = () => {
  if (countdownTimer) {
    clearInterval(countdownTimer)
    countdownTimer = null
    countdownTime.value = 15
    monitoringLading.value = false
  }
}

// 监测计时
let reckonTimer = null
const reckonTime = async () => {
  if (reckonTimer) {
    clearInterval(reckonTimer)
  }
  let seconds = 0
  if (!examDatetime.value) {
    await getExamStatus_(deviceSn.value)
  }
  const timeDiff = Math.floor((new Date() - new Date(examDatetime.value)) / 1000)
  seconds = timeDiff > 0 ? timeDiff : 0 // 防止负数的情况

  reckonTimer = setInterval(() => {
    seconds++
    const hours = String(Math.floor(seconds / 3600)).padStart(2, '0')
    const minutes = String(Math.floor((seconds % 3600) / 60)).padStart(2, '0')
    const secs = String(seconds % 60).padStart(2, '0')
    // 输出格式：hh时mm分ss秒
    timingTime.value = `${hours}小时${minutes}分${secs}秒`
  }, 1000)
}
// 结束计时
const clearTime = () => {
  if (reckonTimer) {
    clearInterval(reckonTimer)
  }
  reckonTimer = null
  timingTime.value = null
}

defineExpose({
  deviceScroll,
})
</script>
<style lang="scss" scoped>
.device-report {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  height: auto;

  .title-bind {
    background: linear-gradient(180deg, #eef5fd 0%, #dfecf6 100%);
    border-radius: 20rpx 20rpx 0rpx 0rpx;
  }
  .title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: -webkit-fill-available;
    height: 70rpx !important;
    padding: 0 26rpx;
    .title-width {
      width: 67%;
    }
    .name-box {
      display: flex;
      align-items: baseline;
      .name {
        max-width: 40%;
        font-size: 26rpx;
        color: #000000;
      }
      .sn {
        max-width: 52%;
        font-size: 24rpx;
        color: #666666;
      }
    }
  }
  .content {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: -webkit-fill-available;
    height: auto;
    padding: 26rpx 30rpx 48rpx 30rpx;
    .content-box {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      width: 100%;
      text-align: center;
      .empty-img {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        width: 100%;
        margin: 20rpx auto 20rpx;
        text-align: center;
      }
      .process-img {
        display: flex;
        align-items: center;
        justify-content: space-around;
        width: 100%;
        margin: 20rpx auto 20rpx;
        text-align: center;
      }
      .login {
        font-size: 32rpx;
        color: #666666;
        .red {
          color: $uv-primary;
        }
      }
      .info {
        width: 100%;
        font-size: 26rpx;
        color: #666666;
      }
      .button-box {
        width: 94%;
        margin: 40rpx auto 0;
      }

      .dynamic-text {
        margin-bottom: 40rpx;
        font-family:
          PingFangSC,
          PingFang SC;
        font-size: 32rpx;
        font-weight: 500;
        color: #000000;
      }
      .bind-icon {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        line-height: 30rpx;
      }
    }
  }
}
.battery {
  position: absolute;
  top: 16rpx;
  right: 30rpx;
  display: flex;
  align-items: center;
  .text {
    margin-right: 4rpx;
    font-size: 22rpx;
    color: #999999;
  }
  .main-body {
    position: relative;
    width: 44rpx;
    height: 20rpx;
    margin-right: 2rpx;
    border: 3rpx solid #999999;
    border-radius: 6rpx;
    .electricity {
      position: absolute;
      top: 2rpx;
      right: 2rpx;
      width: 41rpx;
      height: 16rpx;
      .capacity-empty {
        position: relative;
        top: -18rpx;
        left: 18rpx;
        z-index: 9;
        width: 4rpx;
        height: 46rpx;
        background: #ffffff;
        border-left: 2rpx solid #cccccc;
        transform: rotate(-45deg);
      }
      .capacity {
        position: absolute;
        width: 0%;
        height: 100%;
        background: none;
        border-radius: 4rpx;
      }
    }
  }
  .right-head {
    width: 4rpx;
    height: 14rpx;
    background: #999999;
    border-radius: 0 50% 50% 0;
  }
}
</style>
